home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 28
/
Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso
/
Aminet
/
dev
/
lang
/
fpcsrc.lha
/
fpc
/
compiler
/
ag386att.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1998-09-24
|
26KB
|
758 lines
{
$Id: ag386att.pas,v 1.1.1.1 1998/03/25 11:18:12 root Exp $
Copyright (c) 1996-98 by the FPC development team
This unit implements an asmoutput class for i386 AT&T syntax
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************
}
unit ag386att;
interface
uses aasm,assemble;
type
pi386attasmlist=^ti386attasmlist;
ti386attasmlist = object(tasmlist)
procedure WriteTree(p:paasmoutput);virtual;
procedure WriteAsmList;virtual;
end;
implementation
uses
dos,globals,systems,cobjects,i386,
strings,files,verbose
{$ifdef GDB}
,gdb
{$endif GDB}
;
const
line_length = 70;
var
infile : pextfile;
includecount,
lastline : longint;
function getreferencestring(const ref : treference) : string;
var
s : string;
begin
if ref.isintvalue then
s:='$'+tostr(ref.offset)
else
begin
with ref do
begin
{ have we a segment prefix ? }
{ These are probably not correctly handled under GAS }
{ should be replaced by coding the segment override }
{ directly! - DJGPP FAQ }
if segment<>R_DEFAULT_SEG then
s:=att_reg2str[segment]+':'
else
s:='';
if assigned(symbol) then
s:=s+symbol^;
if offset<0 then
s:=s+tostr(offset)
else
if (offset>0) then
begin
if assigned(symbol) then
s:=s+'+'+tostr(offset)
else
s:=s+tostr(offset);
end;
if (index<>R_NO) and (base=R_NO) then
Begin
s:=s+'(,'+att_reg2str[index];
if scalefactor<>0 then
s:=s+','+tostr(scalefactor)+')'
else
s:=s+')';
end
else
if (index=R_NO) and (base<>R_NO) then
s:=s+'('+att_reg2str[base]+')'
else
if (index<>R_NO) and (base<>R_NO) then
Begin
s:=s+'('+att_reg2str[base]+','+att_reg2str[index];
if scalefactor<>0 then
s:=s+','+tostr(scalefactor)+')'
else
s := s+')';
end;
end;
end;
getreferencestring:=s;
end;
function getopstr(t : byte;o : pointer) : string;
var
hs : string;
begin
case t of
top_reg : getopstr:=att_reg2str[tregister(o)];
top_ref : getopstr:=getreferencestring(preference(o)^);
top_const : getopstr:='$'+tostr(longint(o));
top_symbol : begin
hs[0]:=chr(strlen(pchar(pcsymbol(o)^.symbol)));
move(pchar(pcsymbol(o)^.symbol)^,hs[2],byte(hs[0]));
inc(byte(hs[0]));
hs[1]:='$';
if pcsymbol(o)^.offset>0 then
hs:=hs+'+'+tostr(pcsymbol(o)^.offset)
else
if pcsymbol(o)^.offset<0 then
hs:=hs+tostr(pcsymbol(o)^.offset);
getopstr:=hs;
end;
else
internalerror(10001);
end;
end;
function getopstr_jmp(t : byte;o : pointer) : string;
var
hs : string;
begin
case t of
top_reg : getopstr_jmp:=att_reg2str[tregister(o)];
top_ref : getopstr_jmp:='*'+getreferencestring(preference(o)^);
top_const : getopstr_jmp:=tostr(longint(o));
top_symbol : begin
hs[0]:=chr(strlen(pchar(pcsymbol(o)^.symbol)));
move(pchar(pcsymbol(o)^.symbol)^,hs[1],byte(hs[0]));
if pcsymbol(o)^.offset>0 then
hs:=hs+'+'+tostr(pcsymbol(o)^.offset)
else
if pcsymbol(o)^.offset<0 then
hs:=hs+tostr(pcsymbol(o)^.offset);
getopstr_jmp:=hs;
end;
else
internalerror(10001);
end;
end;
var
MMXWarn : boolean;
procedure MMXWarning;
begin
if not MMXWarn then
begin
Message(assem_w_mmxwarning_as_281);
MMXWarn:=true;
end;
end;
{****************************************************************************
TI386ATTASMOUTPUT
****************************************************************************}
{$ifdef GDB}
var
n_line : byte; { different types of source lines }
{$endif}
const
ait_const2str : array[ait_const_32bit..ait_const_8bit] of string[8]=
(#9'.long'#9,'',#9'.short'#9,#9'.byte'#9);
{$ifdef MAKELIB}
const
nameindex : longint = 0;
var
path, filename : string;
procedure getnextname(var filename : string);
begin
inc(nameindex);
if nameindex>999999 then
begin
exterror:=strpnew(' too many assembler files ');
fatalerror(user_defined);
end;
filename:='as'+tostr(nameindex);
end;
{$endif MAKELIB}
procedure ti386attasmlist.WriteTree(p:paasmoutput);
type
twowords=record
word1,word2:word;
end;
var
ch : char;
hp : pai;
consttyp : tait;
s : string;
found : boolean;
i,pos,l : longint;
{$ifdef GDB}
funcname : pchar;
linecount : longint;
{$endif GDB}
begin
{$ifdef GDB}
funcname:=nil;
linecount:=1;
{$endif GDB}
hp:=pai(p^.first);
while assigned(hp) do
begin
{ write debugger informations }
{$ifdef GDB}
if cs_debuginfo in aktswitches then
begin
if not (hp^.typ in [ait_external,ait_stabn,ait_stabs,
{$ifdef MAKELIB}
ait_cut,
{$endif MAKELIB}
ait_stab_function_name]) then
begin
if assigned(hp^.infile) and (pextfile(hp^.infile)<>infile) then
begin
infile:=hp^.infile;
inc(includecount);
if (hp^.infile^.path^<>'') then
begin
AsmWriteLn(#9'.stabs "'+BsToSlash(FixPath(hp^.infile^.path^))+'",'+tostr(n_includefile)+
',0,0,'+target_info.labelprefix+'text'+ToStr(IncludeCount));
end;
AsmWriteLn(#9'.stabs "'+FixFileName(hp^.infile^.name^+hp^.infile^.ext^)+'",'+tostr(n_includefile)+
',0,0,'+target_info.labelprefix+'text'+ToStr(IncludeCount));
AsmWriteLn(target_info.labelprefix+'text'+ToStr(IncludeCount)+':');
end;
{ file name must be there before line number ! }
if (hp^.line<>lastline) and (hp^.line<>0) then
begin
if (n_line = n_textline) and assigned(funcname) and
(target_info.use_function_relative_addresses) then
begin
AsmWriteLn(target_info.labelprefix+'l'+tostr(linecount)+':');
AsmWriteLn(#9'.stabn '+tostr(n_line)+',0,'+tostr(hp^.line)+','+
target_info.labelprefix+'l'+tostr(linecount)+' - '+StrPas(FuncName));
inc(linecount);
end